package org.mil.logic;


import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.BufferedWriter;
import java.io.File;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;

import java.util.List;

import org.mil.bean.bo.FileInfo;
import org.mil.bean.vo.FileInfoVO;
import org.mil.shell.MediaInfoCLI;

import org.mil.util.FileSystemUtil;
import org.mil.util.TextUtil;

/**
 * 媒体信息的采集器，
 * 并封装了最上面的表示层逻辑
 * @author HZK
 *
 */
public class MediaInfoCollector {
	List<File> files;
	List<FileInfo> fileInfos;
	List<FileInfoVO> fileInfoVOs;
	private int totalFiles=0,totalValidFiles,totalParsed;
	
	PropertyChangeSupport listeners = new PropertyChangeSupport(this);  
	
	/**
	 * 为 侦听器列表中添加一个 监视收集进度（其实就是监听totalParsed的值变动）的监听器
	 * @param listener 要加的监听器
	 */
	public void addCollectionProgressListener(PropertyChangeListener listener) {  
	        listeners.addPropertyChangeListener("totalParsed",listener);  
	    }
	
	/**
	 * 触发收集有新进展（totalParsed属性改变）的事件
	 */
    protected void fireCollectionProgress( Object oldValue, Object newValue) {
        listeners.firePropertyChange("totalParsed", oldValue, newValue);
    }
    
    /**
     * 加载文件列表，这是采集数据前的预备工作
     * @param dirPath
     * @param containSubdir
     */
    public void loadFiles(String dirPath,boolean containSubdir){
    	files=FileSystemUtil.getAllFiles(dirPath, containSubdir);
    	if (files==null) return;
		totalFiles=files.size();	
    }
    
	/**
	 * 根据指定的目录更新本容器的fileInfos及fileInfoVOs
	 * 封装了null容错
	 * @param dirPath 指定的目录
	 * @param containSubdir 是否包含子目录
	 */	
    
	public int collect(String dirPath,boolean containSubdir){			
		if (files==null) loadFiles(dirPath,containSubdir);
		return collect();
	}
	public int collect(){					
		if (files==null) return -1;		
		parse(files);
		return 0;
	}
	
	protected void parse(List<File> files){
		
		fileInfos=new ArrayList<FileInfo>();
		fileInfoVOs=new ArrayList<FileInfoVO>();		
		totalParsed=totalValidFiles=0;
	
		for (File f:files){
			InputStream in=	MediaInfoCLI.exportWholeData(f.getAbsolutePath());
			
			//System.out.println(Arrays.toString(b));
			FileInfo info=FileInfo.newInstance(MediaInfoReader.getInstance().parseXML(in));
			
			if (info!=null) {
				totalValidFiles++;
				info.setHandler(f);
				fileInfos.add(info);
				fileInfoVOs.add(FileInfoVO.newInstance(info));
			}
			else System.out.println("ERROR:cannot parse the file:"+f.getAbsolutePath());
			//System.out.println(f.getName()+":"+f.length()/1024/1024+"MB");
			setTotalParsed(totalParsed+1);
			//monitor.setProgress(totalParsed);
			//monitor.setNote("load "+totalParsed);
			
            
			
		}
	}
	
	/**
	 * 读取报表的默认格式（即报表的栏目列表）
	 * @return
	 */
	private String[] readDefaultColumns(){
		List<String> ss=FileSystemUtil.readEveryLineOfFile(PropertyReader.getReportFormatFile());
		if (ss==null) {
			System.out.println("load Data failure.");
			return null;
		}
		List<String> cols=new LinkedList<String>();
		int i=-1;
		String s;	//当前行
		while (++i<ss.size()){
			s=ss.get(i).trim();
			//空行和注释行直接跳过
			if ("".equals(s)) continue;
			if (s.charAt(0)=='#') continue;
			 String[] tags=s.split(",");
			 for (String tag:tags) 
				 if (!"".equals(tag.trim())) cols.add(tag.trim()); 	
		}
		String[] colss=cols.toArray(new String[0]);
		return colss;
	}	
	
	//TODO !!!tentative
	String fileUrl;String outputType;
	public void configReport(String f,String t){
		fileUrl=f;
		outputType=t;
	}
	
	public int exportReport(){
		return exportReport( fileUrl,outputType);
	}
	
	public int exportReport(String fileUrl,String outputType){
		if (outputType.equalsIgnoreCase("html"))
			return exportReportToHTML(fileUrl,readDefaultColumns());
		else if (outputType.equalsIgnoreCase("txt"))
			return exportReportToPlainText(fileUrl,readDefaultColumns());
		else //默认方式
			return exportReportToHTML(fileUrl,readDefaultColumns());
	}
	
	/**
	 * 输出报表到指定文件，报表的格式（即报表的栏目列表）是默认格式
	 * @param fileUrl 文件路径
	 */
	public int exportReportToPlainText(String fileUrl){
		return exportReportToPlainText(fileUrl,readDefaultColumns());
	}
	/**
	 * 输出报表到指定文件，报表的格式（即报表的栏目列表）是自定义的，
	 * @param fileUrl
	 * @param columns 自定义的栏目列表
	 * @param 导出的项目数，-1为异常
	 */
	public int exportReportToPlainText(String fileUrl,String[] columns ){
		try {
			BufferedWriter out = FileSystemUtil.getWriter(fileUrl);
			for (String col:columns)
				out.append(col).append("\t");
			out.newLine();
			for (FileInfoVO vo:fileInfoVOs){
				for (String col:columns)
					out.append(vo.get(col)).append("\t");
				out.newLine();				
			}
			out.flush();
			out.close();
			
		} catch (IOException e) {			 
			e.printStackTrace();
			return -1;
		}		
		return columns.length;
		
	}
	
	public int  exportReportToHTML(String fileUrl){
		return exportReportToHTML(fileUrl,readDefaultColumns());
	}
	public int exportReportToHTML(String fileUrl,String[] columns ){
		try {
			BufferedWriter out = FileSystemUtil.getWriter(fileUrl);
			String meta="<meta http-equiv=\"content-type\" content=\"text/html; charset=UTF-8\"></meta>";
			String head="Report["+TextUtil.formatDate(Calendar.getInstance())+"]";
			String style="table{border:solid 1px #bcb;border-collapse:collapse;}th,td{border:solid 1px #bcb;}" +
					".tt th{background:#cfc;}";
			out.append("<html><head>").append(meta);
			out.append("<title>").append(head).append("</title>");
			out.newLine();
			out.append("<style>").append(style).append("</style>");
			out.append("</head>");			
			out.newLine();
			out.append("<body>");out.newLine();
			out.append("<table>");out.newLine();
			out.append("<tr class=\"tt\">");
			for (String col:columns)
				out.append("<th>").append(col).append("</th>");
			out.append("</tr>");out.newLine();
			for (FileInfoVO vo:fileInfoVOs){
				out.append("<tr>");
				for (String col:columns)
					out.append("<td>").append(vo.get(col)).append("</td>");
				out.append("</tr>");out.newLine();				
			}
			out.append("</table>").append("</body></html>");
			out.flush();
			out.close();
			
		} catch (IOException e) {			 
			e.printStackTrace();
			return -1;
		}		
		return columns.length;
		
	}

	
	public int getTotalFiles() {
		return totalFiles;
	}

	public void setTotalFiles(int totalFiles) {
		this.totalFiles = totalFiles;
	}

	public int getTotalValidFiles() {
		return totalValidFiles;
	}

	public void setTotalValidFiles(int totalValidFiles) {
		this.totalValidFiles = totalValidFiles;
	}

	public int getTotalParsed() {
		return totalParsed;
	}

	public void setTotalParsed(int t) {
		Integer oldValue=totalParsed;
		totalParsed = t;		
		
		//发布监听事件
		fireCollectionProgress( oldValue, t);
	}

	public static void main(String[] args){
		 long a = System.currentTimeMillis();
		MediaInfoCollector m=new MediaInfoCollector();
		String dir="N:\\Video\\201012";
		//List files=FileSystemUtil.getAllFiles(dir, false);
		//m.update(files.subList(0, 4));
		m.collect(dir, true);
		System.out.println("time:"+(System.currentTimeMillis() - a)+"ms");
		//String[] c=new String[]{"x264_bitrate","fileName","fileSize","x264_ref"};
		//System.out.println(Arrays.toString(m.readDefaultColumns()));
		//m.exportReportToPlainText("d:/4.txt");
		m.exportReportToHTML("d:/v.html");
		System.out.println("total:"+m.totalValidFiles+"/"+m.totalFiles);
		System.out.println("time:"+(System.currentTimeMillis() - a)+"ms");
	}
}
